import traceback
from quart import jsonify
from src.common.models.response import ApiResponse, ResponseCode, ResponseMessage
from src.common.models.status import ResponseStatus
from src.common.middleware.request_id import get_request_id
from src.common.utils.logger import log


class CustomException(Exception):
    """
    自定义异常基类
    """
    def __init__(self, code: int = ResponseCode.INTERNAL_ERROR, message: str = ResponseMessage.INTERNAL_ERROR, data=None):
        self.code = code
        self.message = message
        self.data = data
        super().__init__(self.message)


class ValidationException(CustomException):
    """
    数据验证异常
    """
    def __init__(self, message: str = ResponseMessage.VALIDATION_ERROR, data=None):
        super().__init__(ResponseCode.VALIDATION_ERROR, message, data)


class DatabaseException(CustomException):
    """
    数据库操作异常
    """
    def __init__(self, message: str = ResponseMessage.DATABASE_ERROR, data=None):
        super().__init__(ResponseCode.DATABASE_ERROR, message, data)


class RedisException(CustomException):
    """
    Redis操作异常
    """
    def __init__(self, message: str = ResponseMessage.REDIS_ERROR, data=None):
        super().__init__(ResponseCode.REDIS_ERROR, message, data)


class ExternalApiException(CustomException):
    """
    外部API调用异常
    """
    def __init__(self, message: str = ResponseMessage.EXTERNAL_API_ERROR, data=None):
        super().__init__(ResponseCode.EXTERNAL_API_ERROR, message, data)


class BusinessException(CustomException):
    """
    业务逻辑异常
    用于处理业务规则验证失败、权限不足等业务相关异常
    """
    def __init__(self, message: str = "业务逻辑错误", data=None):
        super().__init__(460, message, data)


class ExceptionHandler:
    """
    统一异常处理中间件
    """
    
    def __init__(self, app):
        self.app = app
        self.init_app(app)
    
    def init_app(self, app):
        """初始化异常处理器"""
        # 注册自定义异常处理器
        app.register_error_handler(CustomException, self.handle_custom_exception)
        app.register_error_handler(ValueError, self.handle_value_error)
        app.register_error_handler(KeyError, self.handle_key_error)
        app.register_error_handler(404, self.handle_not_found)
        app.register_error_handler(405, self.handle_method_not_allowed)
        app.register_error_handler(500, self.handle_internal_error)
        app.register_error_handler(Exception, self.handle_general_exception)
    
    async def handle_custom_exception(self, e: CustomException):
        """处理自定义异常"""
        request_id = get_request_id()
        
        # 记录异常日志
        log.warning(f"Custom exception occurred: {e.message} | RequestId: {request_id}")
        
        response = ApiResponse(
            code=e.code,
            message=e.message,
            data=e.data,
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 200
    
    async def handle_value_error(self, e: ValueError):
        """处理值错误"""
        request_id = get_request_id()
        
        log.warning(f"ValueError occurred: {str(e)} | RequestId: {request_id}")
        
        response = ApiResponse(
            code=ResponseCode.BAD_REQUEST,
            message=f"参数值错误: {str(e)}",
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 400
    
    async def handle_key_error(self, e: KeyError):
        """处理键错误"""
        request_id = get_request_id()
        
        log.warning(f"KeyError occurred: {str(e)} | RequestId: {request_id}")
        
        response = ApiResponse(
            code=ResponseCode.BAD_REQUEST,
            message=f"缺少必要参数: {str(e)}",
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 400
    
    async def handle_not_found(self, e):
        """处理404错误"""
        request_id = get_request_id()
        
        log.warning(f"404 Not Found | RequestId: {request_id}")
        
        response = ApiResponse(
            code=ResponseCode.NOT_FOUND,
            message=ResponseMessage.NOT_FOUND,
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 404
    
    async def handle_method_not_allowed(self, e):
        """处理405错误"""
        request_id = get_request_id()
        
        log.warning(f"405 Method Not Allowed | RequestId: {request_id}")
        
        response = ApiResponse(
            code=ResponseCode.METHOD_NOT_ALLOWED,
            message=ResponseMessage.METHOD_NOT_ALLOWED,
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 405
    
    async def handle_internal_error(self, e):
        """处理500错误"""
        request_id = get_request_id()
        
        log.error(f"500 Internal Server Error: {str(e)} | RequestId: {request_id}")
        log.error(f"Traceback: {traceback.format_exc()}")
        
        response = ApiResponse(
            code=ResponseCode.INTERNAL_ERROR,
            message=ResponseMessage.INTERNAL_ERROR,
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 500
    
    async def handle_general_exception(self, e: Exception):
        """处理通用异常"""
        request_id = get_request_id()
        
        log.error(f"Unhandled exception: {str(e)} | RequestId: {request_id}")
        log.error(f"Traceback: {traceback.format_exc()}")
        
        response = ApiResponse(
            code=ResponseCode.INTERNAL_ERROR,
            message=ResponseMessage.INTERNAL_ERROR,
            request_id=request_id
        )
        
        return jsonify(response.to_dict()), 500